from fastapi import APIRouter, Body, Depends, Request, HTTPException
from app.schemas.user import LoginRequest, SuccessResponse, ErrorResponse, ChangePasswordRequest
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Dict, Any, Union
from app.db.session import get_db
from app.utils.password import verify_password, hash_password
from app.utils.token import create_access_token, get_current_user
from datetime import datetime
router = APIRouter()


@router.post('/login', response_model=Union[SuccessResponse, ErrorResponse], summary="登录")
async def login(request: Request, payload:  LoginRequest = Body(...), db: AsyncSession = Depends(get_db)) -> Dict[str, Any]:
    username = payload.username
    password = payload.password

    sql_1 = text("SELECT * FROM user WHERE email = :username")
    result_1 = await db.execute(sql_1, {"username": username})
    user = result_1.first()

    if not user:
        return {
            "code": 401,
            "error": "用户不存在或密码错误"
        }

    status = user[4]  # 假设 status 字段在第5列
    if status == 0:
        return {
            "code": 403,
            "error": "账号已被禁用，无法登录"
        }

    delete_status = user[5]
    if delete_status == 1:
        return {
            "code": 403,
            "error": "账号已被删除，无法登录"
        }

    hashed_password = user[2]
    if not verify_password(password, hashed_password):
        return {
            "code": 401,
            "error": "用户不存在或密码错误"
        }

    sql_2 = text("SELECT nickname FROM profile WHERE user_id = :id")
    result_2 = await db.execute(sql_2, {"id": user[0]})
    profile = result_2.first()

    if profile and profile[0]:
        nickname = profile[0]
    else:
        nickname = username

    role = user[3]
    if role == 'visitor':
        return {
            "code": 403,
            "error": "用户身份信息不对"
        }

    token = create_access_token(
        data={"sub": {"id": user[0], "username": username, "role": role}})

    client_ip = request.client.host if request.client else None

    sql_3 = text("""
        UPDATE user 
        SET last_login_ip = :ip, 
            last_login_at = :now, 
            updated_at = :now 
        WHERE id = :id
    """)
    try:
        await db.execute(sql_3, {"ip": client_ip, "now": datetime.now(), "id": user[0]})
        await db.commit()
    except Exception as e:
        await db.rollback()
        print("登录更新失败:", e)

    return {
        "code": 0,
        "data": {
            "username": nickname,
            "role": role,
            "token": token
        },
    }


@router.post('/change/password', summary="修改密码")
async def change_password(
    payload: ChangePasswordRequest = Body(...),
    db: AsyncSession = Depends(get_db),
    user_info: Dict[str, Any] = Depends(get_current_user)
) -> Dict[str, Any]:
    # 从token解析出的用户信息 sub 是对象
    sub = user_info.get('sub')
    if not sub or not isinstance(sub, dict):
        raise HTTPException(status_code=401, detail='Token无效，无法获取账号信息')

    user_id = sub.get('id', None)  # type: ignore
    username = sub.get('username', None)  # type: ignore
    if not user_id or not username:
        raise HTTPException(status_code=401, detail='Token无效，无法获取id或账号')

    # 查询用户
    sql = text('SELECT id, password_hash FROM user WHERE id = :id')
    result = await db.execute(sql, {'id': user_id})
    user = result.first()

    if not user:
        return {"code": -1, "error": "用户不存在"}

    # 校验旧密码
    if not verify_password(payload.oldPassword, user[1]):
        return {"code": -1, "error": "旧密码错误"}

    # 更新新密码
    new_hashed = hash_password(payload.newPassword)
    update_sql = text(
        'UPDATE user SET password_hash = :pwd, updated_at = :now WHERE id = :id')
    try:
        await db.execute(update_sql, {'pwd': new_hashed, 'now': datetime.now(), 'id': user_id})
        await db.commit()
        return {"code": 0, "message": "密码修改成功"}
    except Exception as e:
        await db.rollback()
        return {"code": -1, "error": f"修改失败: {str(e)}"}
